package com.mp.approvalreq.service.strategy;

import com.alibaba.fastjson.JSONObject;
import com.mp.approvalreq.entity.Flow;
import com.mp.approvalreq.util.ListHelper;
import com.mp.approvalreq.util.ValidateUtil;
import com.mp.user.entity.User;
import com.mp.user.service.UserServicePrx;
import com.mp.user.util.UserUtils;
import com.plusmoney.util.Utils;
import com.qq.tars.client.util.ServantUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

public class FlowFactory {

    private static final Logger logger = LoggerFactory.getLogger(FlowFactory.class);
    private static final String DEFAULT_FLOW = "default";
    private static final String ALTERNATIVE = "Alternative";

    public static List<Flow> build(User user, String templateFlow, String requestFlow) throws Throwable {
        if (ALTERNATIVE.equals(templateFlow)) {
            return buildRequestFlow(user, requestFlow);
        } else {
            return buildRequestFlow(user, templateFlow);
        }
    }

    private static List<Flow> buildRequestFlow(User user, String requestFlow) throws Throwable {
        List<Flow> flows = new ArrayList<>();
        // 老板默认审批流为自己
        logger.info("requestFlow:{}", requestFlow);
        if (UserUtils.isAdmin(user) && isDefault(requestFlow)) {
            return getAdminFlow(user);
        }
        Map<String, User> userMap = getFlowUserMap(user, requestFlow);
        logger.info("userMap:{}", JSONObject.toJSONString(userMap));
        if (isDefault(requestFlow)) {
            // 默认审批流为各级主管
            int ordering = 1;
            for (User u : userMap.values()) {
                Flow flow = new Flow(u);
                flow.setOrdering(ordering++);
                flows.add(flow);
            }
            if (Utils.isEmpty(flows)) {
                flows = getAdminFlow(user);
            }
            return flows;
        } else {
            List<String> templateFlows = ListHelper.string2StringList(requestFlow);
            int ordering = 1;
            for (String templateFlow : templateFlows) {
                if (templateFlow.contains("||")) {
                    // 或签
                    String[] subFlows = templateFlow.split("\\|\\|");
                    for (String subFlow : subFlows) {
                        Flow flow = getFlow(userMap, ordering, subFlow, Flow.MODE_OR);
                        if (Utils.isNotNull(flow)) {
                            flows.add(flow);
                        }
                    }
                } else if (templateFlow.contains("&&")) {
                    // 会签
                    String[] subFlows = templateFlow.split("&&");
                    for (String subFlow : subFlows) {
                        Flow flow = getFlow(userMap, ordering, subFlow, Flow.MODE_AND);
                        if (Utils.isNotNull(flow)) {
                            flows.add(flow);
                        }
                    }
                } else {
                    // 逐级
                    Flow flow = getFlow(userMap, ordering, templateFlow, Flow.MODE_DEFAULT);
                    if (Utils.isNotNull(flow)) {
                        flows.add(flow);
                    } else {
                        continue;
                    }
                }
                ordering++;
            }

            return Utils.isNotEmpty(flows) ? flows : getAdminFlow(user);

        }

    }

    private static Flow getFlow(Map<String, User> userMap, int ordering, String flowStr, int mode) {
        User user = userMap.get(flowStr);
        if (Utils.isNull(user)) {
            return null;
        }
        Flow flow = new Flow(user);
        flow.setOrdering(ordering);
        flow.setType(mode);
        return flow;
    }

    /**
     * 获取审批流对应的用户集合（key为id、SP、DM）
     *
     * @param user
     * @param requestFlow
     * @return
     * @throws Throwable
     */
    private static Map<String, User> getFlowUserMap(User user, String requestFlow) throws Throwable {
        Map<String, User> map = new LinkedHashMap<>();
        if (StringUtils.isEmpty(requestFlow)) {
            return map;
        }
        if (isDefault(requestFlow) || requestFlow.contains("SP") || requestFlow.contains("DM")) {
            List<User> superiors = getUserSuperiors(user);
            if (isDefault(requestFlow)) {
                for (User superior : superiors) {
                    map.put(String.valueOf(superior.getContactId()), superior);
                }
                return map;
            }
            User sp = getSp(superiors);
            if (Utils.isNotNull(sp)) {
                map.put("SP", sp);
            }
            User dm = getDm(superiors);
            if (Utils.isNotNull(dm)) {
                map.put("DM", dm);
            }
        }

        String filterContactIds = filterNumber(requestFlow);
        if (StringUtils.isBlank(filterContactIds)) {
            return map;
        }

        UserServicePrx userServicePrx = ServantUtils.getObject(UserServicePrx.class);
        List<User> userList = userServicePrx.getUserListByContactIds(filterContactIds);
        for (User u : userList) {
            map.put(String.valueOf(u.getContactId()), u);
        }
        return map;
    }

    /**
     * 筛选审批流中的用户id
     *
     * @param templateFlows
     * @return
     */
    private static String filterNumber(String templateFlows) {
        String str = templateFlows.replaceAll("\\|\\|", ",").replaceAll("&&", ",");
        logger.info("替换会签或签后:{}", str);
        List<String> list = ListHelper.string2StringList(str);

        List<String> filterList = new ArrayList<>();
        for (String s : list) {
            if (ValidateUtil.isInteger(s)) {
                filterList.add(s);
            }
        }
        return ListHelper.list2string(filterList);
    }

    /**
     * 获取所有（正职）上级
     *
     * @param user
     * @return
     * @throws Throwable
     */
    private static List<User> getUserSuperiors(User user) throws Throwable {
        UserServicePrx userServicePrx = ServantUtils.getObject(UserServicePrx.class);
        List<User> superiors = userServicePrx.getSuperiorList(user.getContactId());

        List<User> list = new ArrayList<>(superiors.size());
        for (User superior : superiors) {
            // 过滤正职
            if (UserUtils.isDeptManager(superior) || UserUtils.isAdmin(superior)) {
                list.add(superior);
            }
        }
        return list;
    }

    /**
     * 获取间接上级
     *
     * @param superiors
     * @return
     */
    private static User getDm(List<User> superiors) {
        if (Utils.isEmpty(superiors) || superiors.size() < 2) {
            return null;
        }
        return superiors.get(1);
    }

    /**
     * 获取直接上级
     *
     * @param superiors
     * @return
     */
    private static User getSp(List<User> superiors) {
        if (Utils.isEmpty(superiors)) {
            return null;
        }
        return superiors.get(0);
    }

    //
    private static List<Flow> getAdminFlow(User user) throws Throwable {
        UserServicePrx userServicePrx = ServantUtils.getObject(UserServicePrx.class);

        User admin;
        if (UserUtils.isAdmin(user)) {
            admin = user;
        } else {
            admin = userServicePrx.getAdminUser(user.getCompanyId());
        }
        Flow flow = new Flow(admin);
        flow.setOrdering(1);
        return Collections.singletonList(flow);
    }

    private static boolean isDefault(String requestFlow) {
        return DEFAULT_FLOW.equals(requestFlow);
    }

}
